/**
 * 红外温度分析系统 Web版 - 主要逻辑
 */

class ThermalAnalysisApp {
    constructor() {
        // 应用状态
        this.currentImage = null;
        this.imageFile = null;
        this.selectedRegions = [];
        this.calibrationPoints = [];
        this.currentMode = 'region'; // 'region' 或 'calibration'
        this.isAnalyzing = false;
        this.apiBaseUrl = '/api';
        
        // 标定相关状态
        this.pendingCalibrationPoint = null;
        
        // DOM元素引用
        this.elements = {};
        
        // 初始化应用
        this.init();
    }
    
    /**
     * 初始化应用
     */
    init() {
        console.log('初始化温度分析应用...');
        
        // 获取DOM元素引用
        this.initElements();
        
        // 绑定事件监听器
        this.bindEvents();
        
        // 检查API状态
        this.checkApiStatus();
        
        // 初始化画布管理器
        if (window.CanvasManager) {
            this.canvas = new CanvasManager('canvas-container', {
                onRegionSelected: (region) => this.handleRegionSelected(region),
                onRegionRemoved: (index) => this.handleRegionRemoved(index),
                onCalibrationPointClicked: (coords) => this.handleCalibrationPointClicked(coords),
                onCalibrationPointRemoved: (index) => this.handleCalibrationPointRemoved(index)
            });
        }
        
        console.log('应用初始化完成');
    }
    
    /**
     * 获取DOM元素引用
     */
    initElements() {
        this.elements = {
            // 上传相关
            uploadArea: document.getElementById('upload-area'),
            imageInput: document.getElementById('image-input'),
            imageInfo: document.getElementById('image-info'),
            fileName: document.getElementById('file-name'),
            fileSize: document.getElementById('file-size'),
            imageDimensions: document.getElementById('image-dimensions'),
            
            // 模式切换
            regionModeBtn: document.getElementById('region-mode-btn'),
            calibrationModeBtn: document.getElementById('calibration-mode-btn'),
            
            // 区域管理
            analyzeBtn: document.getElementById('analyze-btn'),
            clearRegionsBtn: document.getElementById('clear-regions-btn'),
            clearCalibrationBtn: document.getElementById('clear-calibration-btn'),
            regionsList: document.getElementById('regions-list'),
            regionCount: document.getElementById('region-count'),
            regionsPanel: document.getElementById('regions-panel'),
            
            // 标定管理
            calibrationPanel: document.getElementById('calibration-panel'),
            calibrationList: document.getElementById('calibration-list'),
            calibrationCount: document.getElementById('calibration-count'),
            autoCalibrateBtn: document.getElementById('auto-calibrate-btn'),
            gridAutoCalibrateBtn: document.getElementById('grid-auto-calibrate-btn'),
            
            // 自动标定模态框
            autoCalibrateModal: document.getElementById('auto-calibrate-modal'),
            rjpegFileInput: document.getElementById('rjpeg-file-input'),
            rjpegPreviewArea: document.getElementById('rjpeg-preview-area'),
            rjpegCanvas: document.getElementById('rjpeg-canvas'),
            rjpegCanvasContainer: document.getElementById('rjpeg-canvas-container'),
            autoCalibrationPointsCount: document.getElementById('auto-calibration-points-count'),
            autoCalibrationPointsList: document.getElementById('auto-calibration-points-list'),
            cancelAutoCalibrateBtn: document.getElementById('cancel-auto-calibrate-btn'),
            confirmAutoCalibrateBtn: document.getElementById('confirm-auto-calibrate-btn'),
            
            // 网格自动标定模态框
            gridAutoCalibrateModal: document.getElementById('grid-auto-calibrate-modal'),
            gridSizeSelect: document.getElementById('grid-size-select'),
            gridRjpegFileInput: document.getElementById('grid-rjpeg-file-input'),
            gridCurrentFile: document.getElementById('grid-current-file'),
            gridCurrentFilename: document.getElementById('grid-current-filename'),
            gridUploadSection: document.getElementById('grid-upload-section'),
            gridPreview: document.getElementById('grid-preview'),
            gridPointsCount: document.getElementById('grid-points-count'),
            cancelGridCalibrateBtn: document.getElementById('cancel-grid-calibrate-btn'),
            confirmGridCalibrateBtn: document.getElementById('confirm-grid-calibrate-btn'),
            
            // 使用说明
            regionInstructions: document.getElementById('region-instructions'),
            calibrationInstructions: document.getElementById('calibration-instructions'),
            
            // 画布相关
            canvasContainer: document.getElementById('canvas-container'),
            placeholder: document.getElementById('placeholder'),
            canvasToolbar: document.getElementById('canvas-toolbar'),
            mouseCoords: document.getElementById('mouse-coords'),
            zoomLevel: document.getElementById('zoom-level'),
            resetZoomBtn: document.getElementById('reset-zoom-btn'),
            
            // 结果展示
            loadingIndicator: document.getElementById('loading-indicator'),
            resultsContainer: document.getElementById('results-container'),
            emptyResults: document.getElementById('empty-results'),
            
            // 状态指示器
            apiStatus: document.getElementById('api-status'),
            uploadStatus: document.getElementById('upload-status'),
            selectedRegions: document.getElementById('selected-regions'),
            footerApiStatus: document.getElementById('footer-api-status'),
            
            // 模态框
            errorModal: document.getElementById('error-modal'),
            errorMessage: document.getElementById('error-message'),
            closeErrorBtn: document.getElementById('close-error-btn'),
            successModal: document.getElementById('success-modal'),
            successMessage: document.getElementById('success-message'),
            closeSuccessBtn: document.getElementById('close-success-btn'),
            
            // 标定输入模态框
            calibrationInputModal: document.getElementById('calibration-input-modal'),
            calibrationCoords: document.getElementById('calibration-coords'),
            calibrationTempInput: document.getElementById('calibration-temp-input'),
            cancelCalibrationBtn: document.getElementById('cancel-calibration-btn'),
            confirmCalibrationBtn: document.getElementById('confirm-calibration-btn'),
            
            // R-JPEG温度获取
            rjpegAutoTempBtn: document.getElementById('rjpeg-auto-temp-btn'),
            rjpegTempFileInput: document.getElementById('rjpeg-temp-file-input'),
            rjpegTempResult: document.getElementById('rjpeg-temp-result'),
            rjpegTempValue: document.getElementById('rjpeg-temp-value'),
            useRjpegTempBtn: document.getElementById('use-rjpeg-temp-btn'),
            rjpegTempLoading: document.getElementById('rjpeg-temp-loading'),
            rjpegTempError: document.getElementById('rjpeg-temp-error')
        };
    }
    
    /**
     * 绑定事件监听器
     */
    bindEvents() {
        // 图片上传事件
        this.elements.uploadArea.addEventListener('click', () => {
            this.elements.imageInput.click();
        });
        
        this.elements.imageInput.addEventListener('change', (e) => {
            this.handleFileSelect(e.target.files[0]);
        });
        
        // 拖拽上传事件
        this.elements.uploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            this.elements.uploadArea.classList.add('drag-over');
        });
        
        this.elements.uploadArea.addEventListener('dragleave', () => {
            this.elements.uploadArea.classList.remove('drag-over');
        });
        
        this.elements.uploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            this.elements.uploadArea.classList.remove('drag-over');
            const file = e.dataTransfer.files[0];
            if (file) {
                this.handleFileSelect(file);
            }
        });
        
        // 分析按钮
        this.elements.analyzeBtn.addEventListener('click', () => {
            if (this.currentMode === 'region') {
                this.analyzeRegions();
            } else if (this.currentMode === 'calibration') {
                this.applyCalibration();
            }
        });
        
        // 清空按钮 - 区域模式
        this.elements.clearRegionsBtn.addEventListener('click', () => {
            if (this.currentMode === 'region') {
                this.clearAllRegions();
            }
        });
        
        // 清空标定按钮 - 标定模式专用
        this.elements.clearCalibrationBtn.addEventListener('click', () => {
            this.clearAllCalibrationPoints();
        });
        
        // 重置缩放按钮
        this.elements.resetZoomBtn.addEventListener('click', () => {
            if (this.canvas) {
                this.canvas.resetZoom();
            }
        });
        
        // 模式切换按钮
        this.elements.regionModeBtn.addEventListener('click', () => {
            this.switchMode('region');
        });
        
        this.elements.calibrationModeBtn.addEventListener('click', () => {
            this.switchMode('calibration');
        });
        
        // 模态框关闭事件
        this.elements.closeErrorBtn.addEventListener('click', () => {
            this.hideModal('error');
        });
        
        this.elements.closeSuccessBtn.addEventListener('click', () => {
            this.hideModal('success');
        });
        
        // 标定输入模态框事件
        this.elements.cancelCalibrationBtn.addEventListener('click', () => {
            this.hideModal('calibration-input');
            this.pendingCalibrationPoint = null;
        });
        
        this.elements.confirmCalibrationBtn.addEventListener('click', () => {
            this.confirmCalibrationPoint();
        });
        
        // 自动标定事件
        this.elements.autoCalibrateBtn.addEventListener('click', () => {
            this.openAutoCalibrationModal();
        });
        
        this.elements.cancelAutoCalibrateBtn.addEventListener('click', () => {
            this.closeAutoCalibrationModal();
        });
        
        this.elements.confirmAutoCalibrateBtn.addEventListener('click', () => {
            this.performAutoCalibration();
        });
        
        // 网格自动标定事件
        this.elements.gridAutoCalibrateBtn.addEventListener('click', () => {
            this.openGridAutoCalibrationModal();
        });
        
        this.elements.cancelGridCalibrateBtn.addEventListener('click', () => {
            this.closeGridAutoCalibrationModal();
        });
        
        this.elements.confirmGridCalibrateBtn.addEventListener('click', () => {
            this.performGridAutoCalibration();
        });
        
        this.elements.gridSizeSelect.addEventListener('change', () => {
            this.updateGridPreview();
        });
        
        this.elements.rjpegFileInput.addEventListener('change', (e) => {
            this.handleRjpegFileUpload(e);
        });
        
        // R-JPEG温度获取事件
        this.elements.rjpegAutoTempBtn.addEventListener('click', () => {
            // 检查当前图片是否为R-JPEG格式
            if (this.imageFile && this.isRjpegFormat(this.imageFile.name)) {
                // 直接使用当前图片进行温度分析
                if (this.pendingCalibrationPoint) {
                    this.getRjpegTemperatureAtPoint(null, this.pendingCalibrationPoint.x, this.pendingCalibrationPoint.y);
                } else {
                    this.showError('请先在图片上选择标定点位置');
                }
            } else {
                // 需要上传R-JPEG文件
                this.elements.rjpegTempFileInput.click();
            }
        });
        
        this.elements.rjpegTempFileInput.addEventListener('change', (e) => {
            this.handleRjpegTempFileUpload(e);
        });
        
        this.elements.useRjpegTempBtn.addEventListener('click', () => {
            this.useRjpegTemperature();
        });
        
        // 回车键确认标定
        this.elements.calibrationTempInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                this.confirmCalibrationPoint();
            }
        });
        
        // 点击模态框背景关闭
        this.elements.errorModal.addEventListener('click', (e) => {
            if (e.target === this.elements.errorModal) {
                this.hideModal('error');
            }
        });
        
        this.elements.successModal.addEventListener('click', (e) => {
            if (e.target === this.elements.successModal) {
                this.hideModal('success');
            }
        });
        
        this.elements.calibrationInputModal.addEventListener('click', (e) => {
            if (e.target === this.elements.calibrationInputModal) {
                this.hideModal('calibration-input');
                this.pendingCalibrationPoint = null;
            }
        });
    }
    
    /**
     * 检查API状态
     */
    async checkApiStatus() {
        try {
            const response = await fetch(`${this.apiBaseUrl}/health`);
            const data = await response.json();
            
            if (data.status === 'healthy') {
                this.updateApiStatus('connected', '已连接');
            } else {
                this.updateApiStatus('disconnected', '连接异常');
            }
        } catch (error) {
            console.error('API状态检查失败:', error);
            this.updateApiStatus('disconnected', '连接失败');
        }
    }
    
    /**
     * 更新API状态指示器
     */
    updateApiStatus(status, text) {
        const statusClass = status === 'connected' ? 'text-emerald-600' : 
                           status === 'loading' ? 'text-blue-600' : 'text-red-600';
        
        this.elements.apiStatus.textContent = text;
        this.elements.apiStatus.className = statusClass;
        this.elements.footerApiStatus.textContent = text;
        this.elements.footerApiStatus.className = statusClass;
    }
    
    /**
     * 处理文件选择
     */
    handleFileSelect(file) {
        if (!file) return;
        
        // 验证文件类型
        const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
        const allowedExtensions = ['.jpg', '.jpeg', '.png', '.rjpeg', '.r.jpg'];
        const fileName = file.name.toLowerCase();
        
        const isValidType = allowedTypes.includes(file.type) || 
                           allowedExtensions.some(ext => fileName.endsWith(ext));
        
        if (!isValidType) {
            this.showError('不支持的文件格式，请选择 JPG、PNG 或 RJPEG 格式的图片');
            return;
        }
        
        // 文件大小检查（最大10MB）
        const maxSize = 10 * 1024 * 1024;
        if (file.size > maxSize) {
            this.showError('文件过大，请选择小于10MB的图片');
            return;
        }
        
        this.imageFile = file;
        this.loadImagePreview(file);
        this.updateImageInfo(file);
        this.clearAllRegions(); // 清空之前的区域
        
        // 如果在标定模式，也清空标定点
        if (this.currentMode === 'calibration') {
            this.calibrationPoints = [];
            this.updateCalibrationList();
            this.updateCalibrationCount();
            if (this.canvas) {
                this.canvas.clearCalibrationPoints();
            }
        }
    }
    
    /**
     * 加载图片预览
     */
    loadImagePreview(file) {
        const reader = new FileReader();
        reader.onload = (e) => {
            const img = new Image();
            img.onload = () => {
                // 更新图片尺寸信息
                this.elements.imageDimensions.textContent = `${img.width} × ${img.height}`;
                
                // 使用画布管理器加载图片
                if (this.canvas) {
                    this.canvas.loadImage(e.target.result);
                    this.elements.placeholder.classList.add('hidden');
                    this.elements.canvasToolbar.classList.remove('hidden');
                    this.elements.resetZoomBtn.disabled = false;
                }
                
                this.updateUploadStatus('已加载');
                console.log('图片加载完成:', file.name, `${img.width}×${img.height}`);
            };
            img.src = e.target.result;
        };
        reader.readAsDataURL(file);
    }
    
    /**
     * 更新图片信息显示
     */
    updateImageInfo(file) {
        this.elements.fileName.textContent = file.name;
        this.elements.fileSize.textContent = this.formatFileSize(file.size);
        this.elements.imageInfo.classList.remove('hidden');
    }
    
    /**
     * 格式化文件大小
     */
    formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }
    
    /**
     * 处理区域选择
     */
    handleRegionSelected(region) {
        this.selectedRegions.push(region);
        this.updateRegionsList();
        this.updateRegionCount();
        this.updateAnalyzeButtonState();
        
        console.log('新区域已选择:', region);
    }
    
    /**
     * 处理区域移除
     */
    handleRegionRemoved(index) {
        if (index >= 0 && index < this.selectedRegions.length) {
            this.selectedRegions.splice(index, 1);
            this.updateRegionsList();
            this.updateRegionCount();
            this.updateAnalyzeButtonState();
            
            // 更新画布显示
            if (this.canvas) {
                this.canvas.updateRegions(this.selectedRegions);
            }
        }
    }
    
    /**
     * 更新区域列表显示
     */
    updateRegionsList() {
        const container = this.elements.regionsList;
        container.innerHTML = '';
        
        this.selectedRegions.forEach((region, index) => {
            const item = document.createElement('div');
            item.className = 'region-item';
            item.innerHTML = `
                <div class="flex items-center justify-between">
                    <div class="flex-1">
                        <span class="font-medium text-gray-900">区域 ${index + 1}</span>
                        <div class="text-xs text-gray-500 mt-1">
                            (${region.x1}, ${region.y1}) → (${region.x2}, ${region.y2})
                        </div>
                        <div class="text-xs text-gray-400">
                            ${region.width} × ${region.height} 像素
                        </div>
                    </div>
                    <button class="remove-btn" data-index="${index}" title="删除区域">
                        ×
                    </button>
                </div>
            `;
            
            // 绑定删除按钮事件
            const removeBtn = item.querySelector('.remove-btn');
            removeBtn.addEventListener('click', () => {
                this.handleRegionRemoved(index);
            });
            
            container.appendChild(item);
        });
    }
    
    /**
     * 更新区域计数
     */
    updateRegionCount() {
        const count = this.selectedRegions.length;
        this.elements.regionCount.textContent = count;
        this.elements.selectedRegions.textContent = `${count}个`;
    }
    
    /**
     * 更新分析按钮状态
     */
    updateAnalyzeButtonState() {
        const hasImage = this.imageFile !== null;
        
        if (this.currentMode === 'region') {
            const hasRegions = this.selectedRegions.length > 0;
            const canAnalyze = hasImage && hasRegions && !this.isAnalyzing;
            
            this.elements.analyzeBtn.disabled = !canAnalyze;
            this.elements.clearRegionsBtn.disabled = this.selectedRegions.length === 0;
            
            if (this.isAnalyzing) {
                this.elements.analyzeBtn.innerHTML = `
                    <div class="flex items-center justify-center">
                        <div class="icon-spin mr-2">⟳</div>
                        分析中...
                    </div>
                `;
            } else {
                this.elements.analyzeBtn.textContent = '分析区域';
            }
        } else if (this.currentMode === 'calibration') {
            const hasCalibrationPoints = this.calibrationPoints.length > 0;
            const canApply = hasImage && hasCalibrationPoints && !this.isAnalyzing;
            
            this.elements.analyzeBtn.disabled = !canApply;
            // 更新标定模式下的清空按钮状态
            this.elements.clearCalibrationBtn.disabled = this.calibrationPoints.length === 0;
            
            if (this.isAnalyzing) {
                this.elements.analyzeBtn.innerHTML = `
                    <div class="flex items-center justify-center">
                        <div class="icon-spin mr-2">⟳</div>
                        应用中...
                    </div>
                `;
            } else {
                // 标定模式下隐藏分析按钮，因为应用标定功能已移除
                this.elements.analyzeBtn.style.display = 'none';
            }
        }
    }
    
    /**
     * 应用标定设置
     */
    async applyCalibration() {
        if (this.calibrationPoints.length === 0) {
            this.showError('请先添加标定点');
            return;
        }
        
        this.showSuccess(`标定设置已应用！共有 ${this.calibrationPoints.length} 个标定点生效`);
    }
    
    /**
     * 清空所有区域
     */
    clearAllRegions() {
        this.selectedRegions = [];
        this.updateRegionsList();
        this.updateRegionCount();
        this.updateAnalyzeButtonState();
        this.clearResults();
        
        // 清空画布区域
        if (this.canvas) {
            this.canvas.clearRegions();
        }
        
        console.log('所有区域已清空');
    }
    
    /**
     * 分析选中区域
     */
    async analyzeRegions() {
        if (!this.imageFile || this.selectedRegions.length === 0) {
            this.showError('请先上传图片并选择分析区域');
            return;
        }
        
        this.isAnalyzing = true;
        this.updateAnalyzeButtonState();
        this.showLoadingIndicator();
        
        try {
            console.log('开始分析区域温度...', this.selectedRegions);
            
            // 准备FormData
            const formData = new FormData();
            formData.append('image', this.imageFile);
            formData.append('regions', JSON.stringify(this.selectedRegions));
            formData.append('save_result', 'false'); // 不保存到服务器
            formData.append('image_source', 'web_analysis');
            
            // 调用API
            const response = await fetch(`${this.apiBaseUrl}/analyze_image`, {
                method: 'POST',
                body: formData
            });
            
            const result = await response.json();
            
            if (result.success) {
                console.log('分析完成:', result);
                this.displayResults(result.data);
                this.showSuccess(`成功分析 ${result.data.length} 个区域的温度数据`);
                
                // 在Canvas上显示温度信息
                this.displayTemperatureOnCanvas(result.data);
            } else {
                throw new Error(result.message || '分析失败');
            }
            
        } catch (error) {
            console.error('分析失败:', error);
            this.showError(`分析失败: ${error.message}`);
        } finally {
            this.isAnalyzing = false;
            this.updateAnalyzeButtonState();
            this.hideLoadingIndicator();
        }
    }
    
    /**
     * 显示分析结果
     */
    displayResults(regions) {
        const container = this.elements.resultsContainer;
        container.innerHTML = '';
        
        this.elements.emptyResults.classList.add('hidden');
        
        regions.forEach((region, index) => {
            const card = this.createResultCard(region, index);
            container.appendChild(card);
        });
        
        // 添加动画效果
        setTimeout(() => {
            container.querySelectorAll('.result-card').forEach((card, index) => {
                setTimeout(() => {
                    card.classList.add('fade-in');
                }, index * 100);
            });
        }, 50);
    }
    
    /**
     * 创建结果卡片
     */
    createResultCard(region, index) {
        const card = document.createElement('div');
        card.className = 'result-card scale-in';
        
        const temp = region.temperature;
        const coords = region.coordinates;
        
        // 根据温度值设置颜色
        const getTemperatureColor = (temp) => {
            if (temp < 0) return 'temp-cold';
            if (temp < 20) return 'temp-normal';
            if (temp < 40) return 'temp-hot';
            return 'temp-very-hot';
        };
        
        card.innerHTML = `
            <div class="region-id">区域 ${region.region_id}</div>
            
            <div class="mb-4">
                <div class="text-sm text-gray-600 mb-2">坐标范围</div>
                <div class="font-mono text-xs text-gray-500">
                    (${coords.x1}, ${coords.y1}) → (${coords.x2}, ${coords.y2})
                </div>
            </div>
            
            <div class="space-y-3">
                <div class="flex items-center justify-between">
                    <span class="text-sm text-gray-600">最低温度</span>
                    <span class="temperature-value ${getTemperatureColor(temp.min_temp)} temp-min">
                        ${temp.min_temp.toFixed(1)}°C
                    </span>
                </div>
                
                <div class="flex items-center justify-between">
                    <span class="text-sm text-gray-600">最高温度</span>
                    <span class="temperature-value ${getTemperatureColor(temp.max_temp)} temp-max">
                        ${temp.max_temp.toFixed(1)}°C
                    </span>
                </div>
                
                <div class="flex items-center justify-between border-t pt-3">
                    <span class="text-sm font-medium text-gray-900">平均温度</span>
                    <span class="temperature-value ${getTemperatureColor(temp.avg_temp)} temp-avg">
                        ${temp.avg_temp.toFixed(1)}°C
                    </span>
                </div>
            </div>
            
            <div class="mt-4 pt-4 border-t border-gray-100">
                <div class="grid grid-cols-2 gap-4 text-xs text-gray-500">
                    <div>
                        <span class="block">最低点位置</span>
                        <span class="font-mono">(${temp.min_position.x}, ${temp.min_position.y})</span>
                    </div>
                    <div>
                        <span class="block">最高点位置</span>
                        <span class="font-mono">(${temp.max_position.x}, ${temp.max_position.y})</span>
                    </div>
                </div>
            </div>
        `;
        
        return card;
    }
    
    /**
     * 清空分析结果
     */
    clearResults() {
        this.elements.resultsContainer.innerHTML = '';
        this.elements.emptyResults.classList.remove('hidden');
    }
    
    /**
     * 显示加载指示器
     */
    showLoadingIndicator() {
        this.elements.loadingIndicator.classList.remove('hidden');
        this.elements.emptyResults.classList.add('hidden');
    }
    
    /**
     * 隐藏加载指示器
     */
    hideLoadingIndicator() {
        this.elements.loadingIndicator.classList.add('hidden');
        if (this.elements.resultsContainer.children.length === 0) {
            this.elements.emptyResults.classList.remove('hidden');
        }
    }
    
    /**
     * 更新上传状态
     */
    updateUploadStatus(status) {
        this.elements.uploadStatus.textContent = status;
    }
    
    /**
     * 显示错误模态框
     */
    showError(message) {
        this.elements.errorMessage.textContent = message;
        this.elements.errorModal.classList.remove('hidden');
        console.error('错误:', message);
    }
    
    /**
     * 显示成功模态框
     */
    showSuccess(message) {
        this.elements.successMessage.textContent = message;
        this.elements.successModal.classList.remove('hidden');
        console.log('成功:', message);
    }
    
    /**
     * 隐藏模态框
     */
    hideModal(type) {
        if (type === 'error') {
            this.elements.errorModal.classList.add('hidden');
        } else if (type === 'success') {
            this.elements.successModal.classList.add('hidden');
        } else if (type === 'calibration-input') {
            this.elements.calibrationInputModal.classList.add('hidden');
        }
    }
    
    /**
     * 在Canvas上显示温度信息
     */
    displayTemperatureOnCanvas(analysisData) {
        if (!this.canvas || !analysisData || analysisData.length === 0) return;
        
        // 为每个区域添加温度信息，适配API返回的数据结构
        const regionsWithTemperature = this.selectedRegions.map((region, index) => {
            if (index < analysisData.length) {
                const tempData = analysisData[index].temperature;
                return {
                    ...region,
                    temperatureData: {
                        min_temp: tempData.min_temp,
                        max_temp: tempData.max_temp,
                        avg_temp: tempData.avg_temp,
                        min_position: tempData.min_position,
                        max_position: tempData.max_position
                    }
                };
            }
            return region;
        });
        
        // 更新Canvas显示温度信息
        this.canvas.updateRegionsWithTemperature(regionsWithTemperature);
    }
    
    /**
     * 切换工作模式
     */
    switchMode(mode) {
        if (this.currentMode === mode) return;
        
        this.currentMode = mode;
        
        // 更新按钮样式
        if (mode === 'region') {
            this.elements.regionModeBtn.className = 'flex-1 bg-gradient-to-r from-emerald-600 to-teal-600 text-white px-3 py-2 rounded-lg font-medium text-sm transition-all duration-300';
            this.elements.calibrationModeBtn.className = 'flex-1 bg-gray-200 text-gray-700 px-3 py-2 rounded-lg font-medium text-sm hover:bg-gray-300 transition-all duration-300';
            
            // 显示/隐藏相关面板
            this.elements.regionsPanel.classList.remove('hidden');
            this.elements.calibrationPanel.classList.add('hidden');
            this.elements.regionInstructions.classList.remove('hidden');
            this.elements.calibrationInstructions.classList.add('hidden');
            
            // 区域模式：显示分析按钮和清空按钮，更新按钮文本
            this.elements.analyzeBtn.style.display = '';
            this.elements.analyzeBtn.textContent = '分析区域';
            this.elements.clearRegionsBtn.style.display = '';
            this.elements.clearRegionsBtn.textContent = '清空';
            
        } else if (mode === 'calibration') {
            this.elements.calibrationModeBtn.className = 'flex-1 bg-gradient-to-r from-blue-600 to-blue-700 text-white px-3 py-2 rounded-lg font-medium text-sm transition-all duration-300';
            this.elements.regionModeBtn.className = 'flex-1 bg-gray-200 text-gray-700 px-3 py-2 rounded-lg font-medium text-sm hover:bg-gray-300 transition-all duration-300';
            
            // 显示/隐藏相关面板
            this.elements.regionsPanel.classList.add('hidden');
            this.elements.calibrationPanel.classList.remove('hidden');
            this.elements.regionInstructions.classList.add('hidden');
            this.elements.calibrationInstructions.classList.remove('hidden');
            
            // 标定模式：隐藏分析按钮和区域清空按钮
            this.elements.analyzeBtn.style.display = 'none';
            this.elements.clearRegionsBtn.style.display = 'none';
            
            // 加载现有标定点
            this.loadCalibrationPoints();
        }
        
        // 更新画布模式
        if (this.canvas) {
            this.canvas.setMode(mode);
        }
        
        this.updateAnalyzeButtonState();
        console.log('切换到模式:', mode);
    }
    
    /**
     * 处理标定点点击
     */
    handleCalibrationPointClicked(coords) {
        if (!this.imageFile) {
            this.showError('请先上传图片');
            return;
        }
        
        // 保存待处理的标定点坐标
        this.pendingCalibrationPoint = coords;
        
        // 显示温度输入模态框
        this.elements.calibrationCoords.textContent = `(${coords.x}, ${coords.y})`;
        this.elements.calibrationTempInput.value = '';
        
        // 更新R-JPEG按钮文本
        if (this.imageFile && this.isRjpegFormat(this.imageFile.name)) {
            this.elements.rjpegAutoTempBtn.textContent = '使用当前图片分析';
            this.elements.rjpegAutoTempBtn.className = 'bg-green-600 text-white px-3 py-1 rounded text-xs hover:bg-green-700 transition-all duration-300';
        } else {
            this.elements.rjpegAutoTempBtn.textContent = '选择R-JPEG文件';
            this.elements.rjpegAutoTempBtn.className = 'bg-purple-600 text-white px-3 py-1 rounded text-xs hover:bg-purple-700 transition-all duration-300';
        }
        
        this.elements.calibrationInputModal.classList.remove('hidden');
        
        // 聚焦输入框
        setTimeout(() => {
            this.elements.calibrationTempInput.focus();
        }, 100);
    }
    
    /**
     * 确认添加标定点
     */
    async confirmCalibrationPoint() {
        const temperature = parseFloat(this.elements.calibrationTempInput.value);
        
        if (isNaN(temperature)) {
            this.showError('请输入有效的温度值');
            return;
        }
        
        if (!this.pendingCalibrationPoint) {
            this.showError('标定点坐标无效');
            return;
        }
        
        try {
            // 首先上传图片以便后端处理
            await this.uploadImageForCalibration();
            
            // 调用标定API
            const response = await fetch(`${this.apiBaseUrl}/calibration`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    action: 'add',
                    x: this.pendingCalibrationPoint.x,
                    y: this.pendingCalibrationPoint.y,
                    temperature: temperature
                })
            });
            
            const result = await response.json();
            
            if (result.success) {
                // 添加到本地标定点列表
                const calibrationPoint = {
                    position: [this.pendingCalibrationPoint.x, this.pendingCalibrationPoint.y],
                    temperature: temperature,
                    index: this.calibrationPoints.length
                };
                
                this.calibrationPoints.push(calibrationPoint);
                
                // 更新Canvas显示
                if (this.canvas) {
                    this.canvas.addCalibrationPoint(calibrationPoint);
                }
                
                // 更新列表显示
                this.updateCalibrationList();
                this.updateCalibrationCount();
                
                // 隐藏模态框
                this.hideModal('calibration-input');
                this.pendingCalibrationPoint = null;
                
                this.showSuccess(`标定点添加成功！当前共有 ${result.calibration_points_count} 个标定点`);
                
            } else {
                throw new Error(result.message || '标定点添加失败');
            }
            
        } catch (error) {
            console.error('标定点添加失败:', error);
            this.showError(`标定点添加失败: ${error.message}`);
        }
    }
    
    /**
     * 上传图片用于标定（如果还未上传）
     */
    async uploadImageForCalibration() {
        if (!this.imageFile) return;
        
        try {
            const formData = new FormData();
            formData.append('image', this.imageFile);
            formData.append('regions', JSON.stringify([{x1: 0, y1: 0, x2: 10, y2: 10}])); // 临时区域
            formData.append('save_result', 'false');
            formData.append('image_source', 'calibration_prep');
            
            // 确保后端加载了图片
            await fetch(`${this.apiBaseUrl}/analyze_image`, {
                method: 'POST',
                body: formData
            });
            
        } catch (error) {
            console.warn('图片预加载失败:', error);
        }
    }
    
    /**
     * 加载现有标定点
     */
    async loadCalibrationPoints() {
        try {
            const response = await fetch(`${this.apiBaseUrl}/calibration`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    action: 'get'
                })
            });
            
            const result = await response.json();
            
            if (result.success) {
                this.calibrationPoints = result.calibration_points || [];
                
                // 更新Canvas显示
                if (this.canvas) {
                    this.canvas.updateCalibrationPoints(this.calibrationPoints);
                }
                
                // 更新列表显示
                this.updateCalibrationList();
                this.updateCalibrationCount();
            }
            
        } catch (error) {
            console.error('加载标定点失败:', error);
        }
    }
    
    /**
     * 处理标定点移除
     */
    handleCalibrationPointRemoved(index) {
        if (index >= 0 && index < this.calibrationPoints.length) {
            this.calibrationPoints.splice(index, 1);
            this.updateCalibrationList();
            this.updateCalibrationCount();
            
            // 更新画布显示
            if (this.canvas) {
                this.canvas.updateCalibrationPoints(this.calibrationPoints);
            }
        }
    }
    
    /**
     * 更新标定点列表显示
     */
    updateCalibrationList() {
        const container = this.elements.calibrationList;
        container.innerHTML = '';
        
        this.calibrationPoints.forEach((point, index) => {
            // 修复数据结构问题
            let position, temperature;
            if (Array.isArray(point.position)) {
                position = point.position;
                temperature = point.temperature;
            } else if (Array.isArray(point.temperature)) {
                position = point.temperature;
                temperature = point.position;
            } else {
                position = [0, 0];
                temperature = point.temperature || point.position;
            }
            
            const positionText = `(${position[0]}, ${position[1]})`;
            const temperatureText = typeof temperature === 'number' ? temperature.toFixed(1) : temperature;

            const item = document.createElement('div');
            item.className = 'calibration-item bg-white border border-gray-200 rounded-lg p-3 transition-all duration-300 hover:border-blue-300 hover:bg-blue-50';
            item.innerHTML = `
                <div class="flex items-center justify-between">
                    <div class="flex-1">
                        <span class="font-medium text-gray-900">标定点 ${index + 1}</span>
                        <div class="text-xs text-gray-500 mt-1">
                            坐标: ${positionText}
                        </div>
                        <div class="text-sm font-medium text-blue-600 mt-1">
                            温度: ${temperatureText}°C
                        </div>
                    </div>
                    <button class="remove-btn bg-red-500 text-white rounded-full w-6 h-6 text-xs hover:bg-red-600 transition-all duration-300" data-index="${index}" title="删除标定点">
                        ×
                    </button>
                </div>
            `;
            
            // 绑定删除按钮事件
            const removeBtn = item.querySelector('.remove-btn');
            removeBtn.addEventListener('click', () => {
                this.removeCalibrationPoint(index);
            });
            
            container.appendChild(item);
        });
    }
    
    /**
     * 更新标定点计数
     */
    updateCalibrationCount() {
        const count = this.calibrationPoints.length;
        this.elements.calibrationCount.textContent = count;
    }
    
    /**
     * 移除标定点
     */
    async removeCalibrationPoint(index) {
        try {
            const response = await fetch(`${this.apiBaseUrl}/calibration`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    action: 'remove',
                    index: index
                })
            });
            
            const result = await response.json();
            
            if (result.success) {
                // 更新本地标定点列表
                this.calibrationPoints = result.calibration_points || [];
                this.updateCalibrationList();
                this.updateCalibrationCount();
                
                // 更新画布显示
                if (this.canvas) {
                    this.canvas.removeCalibrationPoint(index);
                }
                
                this.showSuccess(result.message);
            } else {
                throw new Error(result.message || '删除标定点失败');
            }
            
        } catch (error) {
            console.error('删除标定点失败:', error);
            this.showError(`删除标定点失败: ${error.message}`);
        }
    }
    
    /**
     * 清空所有标定点
     */
    async clearAllCalibrationPoints() {
        try {
            const response = await fetch(`${this.apiBaseUrl}/calibration`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    action: 'clear'
                })
            });
            
            const result = await response.json();
            
            if (result.success) {
                this.calibrationPoints = [];
                this.updateCalibrationList();
                this.updateCalibrationCount();
                
                // 清空画布标定点
                if (this.canvas) {
                    this.canvas.clearCalibrationPoints();
                }
                
                this.showSuccess('所有标定点已清空');
            } else {
                throw new Error(result.message || '清空标定点失败');
            }
            
        } catch (error) {
            console.error('清空标定点失败:', error);
            this.showError(`清空标定点失败: ${error.message}`);
        }
    }
    
    /**
     * 获取当前应用状态
     */
    getAppState() {
        return {
            hasImage: this.imageFile !== null,
            regionsCount: this.selectedRegions.length,
            calibrationCount: this.calibrationPoints.length,
            currentMode: this.currentMode,
            isAnalyzing: this.isAnalyzing,
            imageName: this.imageFile ? this.imageFile.name : null
        };
    }
    
    /**
     * 打开自动标定模态框
     */
    openAutoCalibrationModal() {
        this.autoCalibrationPoints = [];
        this.rjpegImage = null;
        this.updateAutoCalibrationPointsList();
        this.elements.autoCalibrateModal.classList.remove('hidden');
    }
    
    /**
     * 关闭自动标定模态框
     */
    closeAutoCalibrationModal() {
        this.elements.autoCalibrateModal.classList.add('hidden');
        this.elements.rjpegPreviewArea.classList.add('hidden');
        this.elements.rjpegFileInput.value = '';
        this.autoCalibrationPoints = [];
        this.rjpegImage = null;
    }
    
    /**
     * 处理R-JPEG文件上传
     */
    handleRjpegFileUpload(event) {
        const file = event.target.files[0];
        if (!file) return;
        
        const reader = new FileReader();
        reader.onload = (e) => {
            this.rjpegImage = new Image();
            this.rjpegImage.onload = () => {
                this.setupRjpegCanvas();
                this.elements.rjpegPreviewArea.classList.remove('hidden');
            };
            this.rjpegImage.src = e.target.result;
        };
        reader.readAsDataURL(file);
    }
    
    /**
     * 设置R-JPEG画布
     */
    setupRjpegCanvas() {
        const canvas = this.elements.rjpegCanvas;
        const ctx = canvas.getContext('2d');
        
        // 设置画布尺寸
        const containerWidth = this.elements.rjpegCanvasContainer.clientWidth - 8; // 减去padding
        const scale = Math.min(containerWidth / this.rjpegImage.width, 400 / this.rjpegImage.height);
        
        canvas.width = this.rjpegImage.width * scale;
        canvas.height = this.rjpegImage.height * scale;
        
        this.rjpegScale = scale;
        
        // 绘制图像
        ctx.drawImage(this.rjpegImage, 0, 0, canvas.width, canvas.height);
        
        // 添加点击事件
        canvas.onclick = (e) => {
            this.handleRjpegCanvasClick(e);
        };
        
        this.drawAutoCalibrationPoints();
    }
    
    /**
     * 处理R-JPEG画布点击
     */
    handleRjpegCanvasClick(event) {
        const rect = this.elements.rjpegCanvas.getBoundingClientRect();
        const canvasX = event.clientX - rect.left;
        const canvasY = event.clientY - rect.top;
        
        // 转换为图像坐标
        const imageX = Math.round(canvasX / this.rjpegScale);
        const imageY = Math.round(canvasY / this.rjpegScale);
        
        // 添加标定点
        this.autoCalibrationPoints.push({ x: imageX, y: imageY });
        this.updateAutoCalibrationPointsList();
        this.drawAutoCalibrationPoints();
        
        // 更新确定按钮状态
        this.elements.confirmAutoCalibrateBtn.disabled = this.autoCalibrationPoints.length === 0;
    }
    
    /**
     * 绘制自动标定点
     */
    drawAutoCalibrationPoints() {
        if (!this.rjpegImage) return;
        
        const canvas = this.elements.rjpegCanvas;
        const ctx = canvas.getContext('2d');
        
        // 重新绘制图像
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(this.rjpegImage, 0, 0, canvas.width, canvas.height);
        
        // 绘制标定点
        this.autoCalibrationPoints.forEach((point, index) => {
            const canvasX = point.x * this.rjpegScale;
            const canvasY = point.y * this.rjpegScale;
            
            // 绘制圆点
            ctx.beginPath();
            ctx.arc(canvasX, canvasY, 8, 0, 2 * Math.PI);
            ctx.fillStyle = '#8b5cf6'; // purple-500
            ctx.fill();
            ctx.strokeStyle = 'white';
            ctx.lineWidth = 2;
            ctx.stroke();
            
            // 绘制序号
            ctx.fillStyle = 'white';
            ctx.font = '12px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(index + 1, canvasX, canvasY + 4);
        });
    }
    
    /**
     * 更新自动标定点列表
     */
    updateAutoCalibrationPointsList() {
        const container = this.elements.autoCalibrationPointsList;
        const count = this.elements.autoCalibrationPointsCount;
        
        container.innerHTML = '';
        count.textContent = this.autoCalibrationPoints.length;
        
        this.autoCalibrationPoints.forEach((point, index) => {
            const item = document.createElement('div');
            item.className = 'flex items-center justify-between bg-purple-50 border border-purple-200 rounded-lg px-3 py-2 text-sm';
            item.innerHTML = `
                <span class="font-mono text-purple-800">点${index + 1}: (${point.x}, ${point.y})</span>
                <button class="text-red-500 hover:text-red-700 remove-auto-point-btn" data-index="${index}">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
                    </svg>
                </button>
            `;
            
            // 绑定删除按钮
            const removeBtn = item.querySelector('.remove-auto-point-btn');
            removeBtn.addEventListener('click', () => {
                this.removeAutoCalibrationPoint(index);
            });
            
            container.appendChild(item);
        });
    }
    
    /**
     * 删除自动标定点
     */
    removeAutoCalibrationPoint(index) {
        this.autoCalibrationPoints.splice(index, 1);
        this.updateAutoCalibrationPointsList();
        this.drawAutoCalibrationPoints();
        this.elements.confirmAutoCalibrateBtn.disabled = this.autoCalibrationPoints.length === 0;
    }
    
    /**
     * 执行自动标定
     */
    async performAutoCalibration() {
        if (this.autoCalibrationPoints.length === 0) {
            this.showError('请先选择标定点位置');
            return;
        }
        
        const rjpegFile = this.elements.rjpegFileInput.files[0];
        if (!rjpegFile) {
            this.showError('请先上传R-JPEG文件');
            return;
        }
        
        try {
            this.elements.confirmAutoCalibrateBtn.disabled = true;
            this.elements.confirmAutoCalibrateBtn.textContent = '标定中...';
            
            const formData = new FormData();
            formData.append('rjpeg_file', rjpegFile);
            formData.append('action', 'auto_calibrate');
            formData.append('positions', JSON.stringify(this.autoCalibrationPoints));
            
            const response = await fetch(`${this.apiBaseUrl}/calibration`, {
                method: 'POST',
                body: formData
            });
            
            const result = await response.json();
            
            if (result.success) {
                this.showSuccess(`${result.message} - 已自动创建${result.total_points}个标定点`);
                
                // 关闭模态框
                this.closeAutoCalibrationModal();
                
                // 重新加载标定点列表
                this.loadCalibrationPoints();
                
                console.log('自动标定结果:', result.calibration_results);
            } else {
                throw new Error(result.message || '自动标定失败');
            }
            
        } catch (error) {
            console.error('自动标定失败:', error);
            this.showError(`自动标定失败: ${error.message}`);
        } finally {
            this.elements.confirmAutoCalibrateBtn.disabled = false;
            this.elements.confirmAutoCalibrateBtn.textContent = '开始自动标定';
        }
    }
    
    /**
     * 处理R-JPEG文件上传（用于获取单点温度）
     */
    handleRjpegTempFileUpload(event) {
        const file = event.target.files[0];
        if (!file) return;
        
        if (!this.pendingCalibrationPoint) {
            this.showError('请先在图片上选择标定点位置');
            return;
        }
        
        this.getRjpegTemperatureAtPoint(file, this.pendingCalibrationPoint.x, this.pendingCalibrationPoint.y);
    }
    
    /**
     * 获取R-JPEG文件中指定点的温度
     */
    async getRjpegTemperatureAtPoint(rjpegFile, x, y) {
        try {
            // 显示加载状态
            this.elements.rjpegTempLoading.classList.remove('hidden');
            this.elements.rjpegTempResult.classList.add('hidden');
            this.elements.rjpegTempError.classList.add('hidden');
            
            // 检查是否可以使用当前已上传的图片（如果是R-JPEG格式）
            let fileToUse = rjpegFile;
            if (!rjpegFile && this.imageFile && this.isRjpegFormat(this.imageFile.name)) {
                fileToUse = this.imageFile;
                console.log('使用当前已上传的R-JPEG图片进行温度分析');
            }
            
            if (!fileToUse) {
                throw new Error('没有可用的R-JPEG文件');
            }
            
            const formData = new FormData();
            formData.append('rjpeg_file', fileToUse);
            formData.append('positions', JSON.stringify([{ x: x, y: y }]));
            
            // 先处理R-JPEG文件
            const processResponse = await fetch(`${this.apiBaseUrl}/tsdk/process_rjpeg`, {
                method: 'POST',
                body: formData
            });
            
            if (!processResponse.ok) {
                throw new Error(`处理R-JPEG文件失败: ${processResponse.status}`);
            }
            
            // 获取指定点的温度
            const formData2 = new FormData();
            formData2.append('rjpeg_file', fileToUse);
            formData2.append('action', 'get_point_temperature');
            formData2.append('x', x.toString());
            formData2.append('y', y.toString());
            
            const response = await fetch(`${this.apiBaseUrl}/tsdk/get_point_temperature`, {
                method: 'POST',
                body: formData2
            });
            
            const result = await response.json();
            
            if (result.success && result.temperature !== undefined) {
                // 显示温度结果
                this.elements.rjpegTempValue.textContent = `${result.temperature.toFixed(1)}°C`;
                this.elements.rjpegTempResult.classList.remove('hidden');
                this.rjpegTemperature = result.temperature;
                
                console.log(`R-JPEG温度分析: 坐标(${x}, ${y}) -> ${result.temperature.toFixed(1)}°C`);
            } else {
                throw new Error(result.message || '获取温度失败');
            }
            
        } catch (error) {
            console.error('获取R-JPEG温度失败:', error);
            this.elements.rjpegTempError.textContent = `获取温度失败: ${error.message}`;
            this.elements.rjpegTempError.classList.remove('hidden');
        } finally {
            this.elements.rjpegTempLoading.classList.add('hidden');
        }
    }
    
    /**
     * 使用R-JPEG分析的温度值
     */
    useRjpegTemperature() {
        if (this.rjpegTemperature !== undefined) {
            this.elements.calibrationTempInput.value = this.rjpegTemperature.toFixed(1);
            this.elements.calibrationTempInput.focus();
        }
    }
    
    /**
     * 检查文件是否为R-JPEG格式
     */
    isRjpegFormat(filename) {
        const name = filename.toLowerCase();
        return name.endsWith('.rjpeg') || name.endsWith('.r.jpg') || name.includes('dji') || name.includes('flir');
    }
    
    /**
     * 打开网格自动标定模态框
     */
    openGridAutoCalibrationModal() {
        // 检查当前图片是否为R-JPEG格式
        if (this.imageFile && this.isRjpegFormat(this.imageFile.name)) {
            // 显示当前文件信息
            this.elements.gridCurrentFilename.textContent = this.imageFile.name;
            this.elements.gridCurrentFile.classList.remove('hidden');
            this.elements.gridUploadSection.classList.add('hidden');
        } else {
            // 显示上传选项
            this.elements.gridCurrentFile.classList.add('hidden');
            this.elements.gridUploadSection.classList.remove('hidden');
        }
        
        this.updateGridPreview();
        this.elements.gridAutoCalibrateModal.classList.remove('hidden');
    }
    
    /**
     * 关闭网格自动标定模态框
     */
    closeGridAutoCalibrationModal() {
        this.elements.gridAutoCalibrateModal.classList.add('hidden');
        this.elements.gridRjpegFileInput.value = '';
    }
    
    /**
     * 更新网格预览信息
     */
    updateGridPreview() {
        const gridSize = this.elements.gridSizeSelect.value;
        const [width, height] = gridSize.split('x').map(Number);
        const totalPoints = width * height;
        
        this.elements.gridPointsCount.textContent = totalPoints;
        this.elements.gridPreview.classList.remove('hidden');
    }
    
    /**
     * 执行网格自动标定
     */
    async performGridAutoCalibration() {
        const gridSize = this.elements.gridSizeSelect.value;
        
        // 确定使用的R-JPEG文件
        let rjpegFile = this.elements.gridRjpegFileInput.files[0];
        
        // 如果没有上传新文件，检查当前图片是否为R-JPEG
        if (!rjpegFile && this.imageFile && this.isRjpegFormat(this.imageFile.name)) {
            rjpegFile = this.imageFile;
        }
        
        if (!rjpegFile) {
            this.showError('请上传R-JPEG文件或确保当前图片为R-JPEG格式');
            return;
        }
        
        try {
            this.elements.confirmGridCalibrateBtn.disabled = true;
            this.elements.confirmGridCalibrateBtn.textContent = '网格标定中...';
            
            const fullCoverage = document.getElementById('full-coverage-checkbox').checked;
            
            const formData = new FormData();
            formData.append('rjpeg_file', rjpegFile);
            formData.append('action', 'grid_auto_calibrate');
            formData.append('grid_size', gridSize);
            formData.append('full_coverage', fullCoverage.toString());
            
            const response = await fetch(`${this.apiBaseUrl}/calibration`, {
                method: 'POST',
                body: formData
            });
            
            const result = await response.json();
            
            if (result.success) {
                this.showSuccess(`${result.message} - 成功创建${result.total_points}个网格标定点`);
                
                // 关闭模态框
                this.closeGridAutoCalibrationModal();
                
                // 重新加载标定点列表
                this.loadCalibrationPoints();
                
                console.log('网格自动标定结果:', result);
            } else {
                throw new Error(result.message || '网格自动标定失败');
            }
            
        } catch (error) {
            console.error('网格自动标定失败:', error);
            this.showError(`网格自动标定失败: ${error.message}`);
        } finally {
            this.elements.confirmGridCalibrateBtn.disabled = false;
            this.elements.confirmGridCalibrateBtn.textContent = '开始网格标定';
        }
    }
}

// ==================== 工具函数 ====================

/**
 * 格式化温度值
 */
function formatTemperature(temp) {
    return Number(temp).toFixed(1) + '°C';
}

/**
 * 格式化坐标
 */
function formatCoordinate(x, y) {
    return `(${x}, ${y})`;
}

/**
 * 防抖函数
 */
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

/**
 * 节流函数
 */
function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    }
}

// ==================== 应用启动 ====================

// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', () => {
    console.log('页面加载完成，启动应用...');
    window.thermalApp = new ThermalAnalysisApp();
});

// 错误处理
window.addEventListener('error', (e) => {
    console.error('全局错误:', e.error);
    if (window.thermalApp) {
        window.thermalApp.showError('发生意外错误，请刷新页面重试');
    }
});

// 在页面卸载前清理资源
window.addEventListener('beforeunload', () => {
    if (window.thermalApp && window.thermalApp.canvas) {
        window.thermalApp.canvas.cleanup();
    }
});